package com.celesea.auth.user.service;

import com.celesea.auth.dept.entity.Dept;
import com.celesea.auth.dept.service.DeptService;
import com.celesea.auth.grade.entity.Grade;
import com.celesea.auth.grade.service.GradeService;
import com.celesea.auth.user.dao.UserDao;
import com.celesea.auth.user.entity.User;
import com.celesea.auth.user.entity.UserPerm;
import com.celesea.auth.user.vo.UserFilter;
import com.celesea.auth.user.vo.UserVo;
import com.celesea.framework.dao.Filter;
import com.celesea.framework.entity.BusEntity;
import com.celesea.framework.service.AbstractBaseService;
import com.celesea.framework.util.*;
import com.celesea.framework.vo.DictionaryVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import tk.mybatis.mapper.entity.Example;

import java.util.List;

/**
 * @author JackYuan
 * @create 2017-10-30 23:05
 */
@Service
public class UserServiceImpl extends AbstractBaseService<User> implements UserService {

    public static final String PY_CHARS = "pyChars";
    @Autowired
    private UserDao userDao;
    @Autowired
    private DeptService deptService;
    @Autowired
    private GradeService gradeService;
    @Autowired
    private UserPermService userPermService;

    @Override
    public UserVo insert(UserVo entity) {
        Assert.isTrue(super.checkUnique(entity.toUnique()),"用户账号重复");
        User user = entity.toEntity();
        processCompanyByDept(user);
        super.insert(user);
        entity.setId(user.getId());
        if (Const.Bool.isTrue(user.getPermFlag())) {
            userPermService.insertList(entity.getUserPerms());
        }
        return entity;
    }


    @Override
    public UserVo update(UserVo entity) {
        Assert.isTrue(super.checkUnique(entity.toUnique()),"用户账号重复");
        User user = entity.toEntity();
        processCompanyByDept(user);
        super.update(user);
        userPermService.deleteByUser(entity.getId());
        if (Const.Bool.isTrue(user.getPermFlag())) {
            userPermService.insertList(entity.getUserPerms());
        }
        return entity;
    }


    private void processCompanyByDept(User entity) {
        Assert.notNull(entity.getDeptId(), "所属部门不能为空！");
        entity.setCompany(entity.getId());
        Dept dept = deptService.selectById(entity.getDeptId());
        Assert.notNull(dept, "所属部门不能存在！");
        Assert.notNull(dept.getCompany(), "所属部门没有归属公司信息！");
        entity.setCompany(dept.getCompany());
    }

    @Override
    public PageData<User> selectPage(Filter filter, Page page, Sort sort) {
        PageData<User> users = super.selectPage(filter, page, sort);
        users.append(PY_CHARS, userDao.selectPyChars(filter));
        return users;
    }

    @Override
    public UserVo selectById(String id) {
        User user = super.selectById(id);
        UserVo userVo = new UserVo(user);

        if (StringKit.isNotEmpty(user.getDeptId())) {
            Dept dept = deptService.selectById(user.getDeptId());
            userVo.setDept(new DictionaryVo(dept.getId(), dept.getName()));
        }

        if (StringKit.isNotEmpty(user.getGradeId())) {
            Grade grade = gradeService.selectById(user.getGradeId());
            userVo.setGrade(new DictionaryVo(grade.getId(), grade.getName()));
        }

        if (StringKit.isNotEmpty(user.getLeaderId())) {
            User leader = super.selectById(user.getLeaderId());
            userVo.setLeader(new DictionaryVo(leader.getId(), leader.getName()));
        }
        if (Const.Bool.isTrue(user.getPermFlag())) {
            List<UserPerm> userPerms = userPermService.findByUser(id);
            userVo.setUserPerms(userPerms);
        }
        return userVo;
    }

    @Override
    public List<User> selectByDept(UserFilter filter) {
        Example example = new Example(User.class);
        Example.Criteria criteria1 = example.createCriteria();
        criteria1.andEqualTo("deptId", filter.getDeptId());
        criteria1.andEqualTo("tenantId", filter.getTenantId());
        List<User> users = userDao.selectByExample(example);
        return users;
    }

    @Override
    public User selectByAccount(String tenantId, String account) {
        Assert.notNull(account, "参数不能为空！");
        Example example = new Example(User.class);
        Example.Criteria criteria1 = example.createCriteria();
        criteria1.andEqualTo("tenantId", tenantId);
        criteria1.andEqualTo("account", account);
        List<User> users = userDao.selectByExample(example);
        Assert.notEmpty(users, "不存在用户：" + account);
        return users.get(0);
    }


    @Override
    public List<User> selectByRole(String tenantId, String roleId) {
        return userDao.selectByRole(tenantId, roleId);
    }

    public List<User> selectByGroup(String tenantId, String groupId) {
        return userDao.selectByGroup(tenantId, groupId);
    }

    @Override
    public List<User> findByIds(String tenantId, List<String> ids) {
        Assert.notEmpty(ids, "参数不能为空！");
        Example example = new Example(User.class);
        Example.Criteria criteria1 = example.createCriteria();
        criteria1.andEqualTo("tenantId", tenantId);
        criteria1.andIn("id", ids);
        List<User> users = userDao.selectByExample(example);
        return users;
    }

    @Override
    public void updateFixCompany(String companyId, List<String> childIds) {
        Example example = new Example(User.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo(BusEntity.TALENT_ID, EnvUtil.getTenantId())
                .andIn("deptId", childIds);
        User entity = new User();
        entity.setCompany(companyId);
        userDao.updateByExampleSelective(entity, example);
    }

    @Override
    public User selectByPk(String tenantId, String id) {
        Assert.notNull(id, "参数不能为空！");
        return super.selectById(id);
    }

    @Override
    public List<User> selectByDeptPosition(String tenantId, String deptId, String positionCode) {
        return userDao.selectByDeptPosition(tenantId, deptId, positionCode);
    }
}
